﻿/*!
 * application.Map.js 1.0
 * arcgis 地图 公用操作api
 * 
 * 
 * by liuhao
 */

define(["dojo/_base/declare",
        "dojo/_base/array",
        "esri/map",
        "esri/toolbars/edit",
        "esri/toolbars/draw",
        "esri/SpatialReference",
        "esri/graphic",
        "esri/layers/ClusterLayer",
        "esri/renderers/ClassBreaksRenderer",
        "esri/geometry/Point",
        "esri/geometry/Polyline",
        "esri/geometry/Polygon",
        "esri/geometry/webMercatorUtils",
        "esri/geometry/Multipoint",
        "esri/layers/GoogleLayer",
        "esri/layers/gaodeLayer",
        "esri/layers/BaiduLayer",
        "esri/layers/FeatureLayer",
        "esri/layers/GraphicsLayer",
        "esri/layers/ArcGISDynamicMapServiceLayer",
        "esri/InfoTemplate",
        "esri/tasks/query",
        "esri/symbols/SimpleMarkerSymbol",
        "esri/symbols/SimpleLineSymbol",
        "esri/symbols/SimpleFillSymbol",
        "esri/symbols/TextSymbol",
        "esri/symbols/PictureMarkerSymbol",
        "esri/symbols/PictureFillSymbol",
        "esri/Color",
        "esri/symbols/Font",
        "esri/dijit/BasemapToggle2",
        "dijit/TooltipDialog",
        "dijit/popup",
        "dojo/dom-style",
        "dojo/domReady!"

    ],

    function (declare, arrayUtils, Map, Edit, Draw, SpatialReference, Graphic, ClusterLayer, ClassBreaksRenderer, Point, Polyline, Polygon, webMercatorUtils, Multipoint, GoogleLayer, gaodeLayer, BaiduLayer,
              FeatureLayer, GraphicsLayer, ArcGISDynamicMapServiceLayer,
              InfoTemplate, Query, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, TextSymbol, PictureMarkerSymbol, PictureFillSymbol, Color, Font,
              BasemapToggle2, TooltipDialog, dijitPopup, domStyle) {




        var graphicsLayers = [];
        var flashgraphics = [];

        var drawLyrId = "drawLyrId";

        var m_serverName;
        //var spatialReference = null;
        var layerInfos = []; //图层信息
        var pi = 3.14159265358979324;
        var x_pi = 3.14159265358979324 * 3000.0 / 180.0;
        var agstoken = "";
        declare("map.Draw", null,
            {
                appMap: null,
                drawTool: null,
                editTool: null,
                spatialReference: null,
                constructor: function (map, spatialReference) {
                    if (!map) {
                        console.log("未设置地图对象!");
                        return;
                    }
                    this.appMap = map;
                    this.spatialReference = spatialReference;
                    this.drawTool = new Draw(map);
                    this.editTool = new Edit(map);


                    //实现闪烁
                    var isSet = false;
                    var intervalProcess1 = setInterval(function () {

                        var index = 0;
                        flashgraphics.forEach(function (graphicItem) {

                            var size = 15;
                            if (isSet)
                                size = 15;
                            else
                                size = 20;


                            if (graphicItem.graphic.symbol.type == "picturemarkersymbol") {
                                graphicItem.graphic.symbol.setHeight(size + 10);
                                graphicItem.graphic.symbol.setWidth(size + 10);
                            }
                            else
                                graphicItem.graphic.symbol.setSize(size);

                            graphicItem.flashCount++;
                            if (graphicItem.flashCount >= graphicItem.flashTime * 2) {
                                flashgraphics.splice(index, 1); //移除
                            }

                        });

                        if (flashgraphics.length > 0) {
                            graphicsLayers.forEach(function (item) { item.refresh() });
                        }

                        isSet = !isSet;
                    }, 500);
                    //clearInterval(intervalProcess); //清除定时器

                },
                //画一个图标点
                //            "x": locationPoint.x, 不为空
                //            "y": locationPoint.y,  不为空
                //var options = {
                //        layerid:图形图层id
                //            "symbolUrl" 付号 //可为空
                //             symbolStyle :{width:24,height:24, angle:0,r:0,g:0,b:0,a:1,xOffset,yOffset }
                //            "callBack" 图标的单击事件 //可为空
                //            "attributes" 图标的属性值，可为空
                //             template:{ content:模板内容,attrs:属性值,displayattributes:[{ 中文描述:对应的值},…] }可为空
                //        "isFlash":false
                //        "flashTime":10
                //        };
                drawPoint: function (x, y, options) {
                    if (!$.isNumeric(x) || !$.isNumeric(y)) {
                        console.log("坐标值未设置!");
                        return;
                    }


                    var color = Color.fromArray([226, 119, 40]);

                    if (options && options.symbolStyle) {
                        if (options.symbolStyle.r >= 0 && options.symbolStyle.g >= 0 && options.symbolStyle.b >= 0)
                            color = Color.fromArray([options.symbolStyle.r, options.symbolStyle.g, options.symbolStyle.b]);

                    }

                    var symbol;
                    //设置图片图标
                    if (options && options.symbolUrl) {
                        symbol = new PictureMarkerSymbol({
                            "url": options.symbolUrl,
                            "height": 24,
                            "width": 24,
                            "type": "esriPMS",
                            "angle": 0
                        });
                    }
                    if (options && options.symbolStyle) {
                        if (options.symbolStyle.height) {
                            symbol.height = options.symbolStyle.height;
                        }
                        if (options.symbolStyle.width) {
                            symbol.width = options.symbolStyle.width;
                        }
                        if (options.symbolStyle.angle)
                            symbol.angle = options.symbolStyle.angle;
                    }
                    else {
                        if (!symbol) //默认
                        {
                            symbol = new SimpleMarkerSymbol({
                                color: color,
                                outline: new SimpleLineSymbol({
                                    color: [255, 255, 255],
                                    width: 2
                                })
                            });
                        }
                    }

                    if (options && options.symbolStyle && $.isNumeric(options.symbolStyle.xOffset) && $.isNumeric(options.symbolStyle.yOffset))
                        symbol.setOffset(options.symbolStyle.xOffset, options.symbolStyle.yOffset);


                    var myGraphicsLayer = getGraphicsLayer(this.appMap, options && options.layerid);

                    //图标点击事件
                    if (options && options.callBack)
                        myGraphicsLayer.onClick = options.callBack;

                    //添加图形
                    var point = new Point(x, y, this.spatialReference);
                    var graphic = new Graphic(point, symbol);

                    //设置图标属性信息模板
                    var infoTemplate = setinfoTemplate(options && options.template);
                    if (infoTemplate)
                        graphic.setInfoTemplate(infoTemplate);

                    if (options && options.attributes)
                        graphic.attributes = options.attributes;

                    myGraphicsLayer.add(graphic);

                    //添加点文字
                    if (options && options.title) {

                        this.drawText(options.title, x, y, { layerid: options.layerid, xOffset: 0, yOffset: -25 });
                    }

                    if (options && options.isFlash)
                        flashgraphics.push({ graphic: graphic, flashCount: 0, flashTime: options.flashTime, layerid: options.layerid });

                    return graphic;
                },
                //画线  points:[{x:114,y:24},.....], options={ layerid:图形图层id,
                //isDashdot:true/false,style:{ r:0,g:0,b:255,a:0.75,width:3  },
                //isMoveToLine:true/false, template:{ content:模板内容,attrs:属性值,displayattributes:[{ 中文描述:对应的值},…] }, callBack:function(e){} }
                drawLine: function (points, options) {
                    if (!points || points.length < 2) {
                        console.log("坐标值未设置!");
                        return;
                    }

                    var myGraphicsLayer = getGraphicsLayer(this.appMap, options && options.layerid);

                    if (options && options.callBack)
                        myGraphicsLayer.on("Click", options.callBack);


                    var isarray = false;
                    if ($.isArray(points[0]))
                        isarray = true;

                    var path = [];
                    for (var n = 0; n < points.length; n++) {
                        var p = points[n];
                        if (isarray) {
                            path.push([p[0], p[1]]);
                        }
                        else {
                            path.push([p.x, p.y]);
                        }
                    }

                    var polyline = new Polyline(path);
                    polyline.setSpatialReference(this.spatialReference);

                    //STYLE_DASH	The line is made of dashes.
                    //STYLE_DASHDOT	The line is made of a dash-dot pattern.
                    //STYLE_DASHDOTDOT	The line is made of a dash-dot-dot pattern.
                    //STYLE_DOT	The line is made of dots.
                    //STYLE_LONGDASH	Line is constructed of a series of dashes.
                    //STYLE_LONGDASHDOT	Line is constructed of a series of short dashes.
                    //STYLE_NULL	The line has no symbol.
                    //STYLE_SHORTDASH	Line is constructed of a series of short dashes.
                    //STYLE_SHORTDASHDOT	Line is constructed of a dash followed by a dot.
                    //STYLE_SHORTDASHDOTDOT	Line is constructed of a series of a dash and two dots.
                    //STYLE_SHORTDOT	Line is constructed of a series of short dots.
                    //STYLE_SOLID

                    var style = options.style;
                    var lineStyle = SimpleLineSymbol.STYLE_SOLID;
                    if (options && options.isDashdot)
                        lineStyle = SimpleLineSymbol.STYLE_DASH;

                    var slineSymbol = new SimpleLineSymbol(lineStyle, new Color([0, 0, 255, 0.75]), 3);
                    if (style)
                        slineSymbol = new SimpleLineSymbol(lineStyle, new Color([style.r, style.g, style.b, style.a]), style.width);

                    var graphic = {};
                    var infoTemplate = {};
                    if (options && options.template && options.template.attrs) {
                        graphic = new Graphic(polyline, slineSymbol, options.template.attrs);

                        infoTemplate = setinfoTemplate(options && options.template);
                        if (infoTemplate)
                            graphic.setInfoTemplate(infoTemplate);

                    } else {
                        graphic = new Graphic(polyline, slineSymbol);

                    }
                    //设置图标属性信息模板
                    if (options && options.attributes)
                        graphic.attributes = options.attributes;

                    myGraphicsLayer.add(graphic);

                    //缩放到线
                    if (options && options.isMoveToLine)
                        this.appMap.setExtent(polyline.getExtent(), true);

                    return graphic;
                },
                // 画多边形
                //points:[[114,24],.....]
                //option={ layerid:图形图层id,
                //lineStyle: { r: 0, g: 0, b: 255, a: 0.75, width: 3,isDashdot:true/false},
                //fillPicUrl::/images/mangrove.png, //图片优先，没有图片，就默认
                //fillStyle:{ style: "STYLE_SOLID" , r: 0, g: 0, b: 255, a: 0.75, }
                //isMoveTo:true/false, template:{ content:模板内容,attrs:属性值,displayattributes:[{ 中文描述:对应的值},…] }, callBack:function(e){}
                // attributes:特性}
                drawPolygon: function (points, option) {

                    var myGraphicsLayer = getGraphicsLayer(this.appMap, option && option.layerid);
                    if (option && option.callBack)
                        myGraphicsLayer.on("Click", option.callBack);

                    if (!points || points.length <= 2) {
                        console.log("至少需要三个顶点坐标!");
                        return;
                    }

                    var isarray = false;
                    if ($.isArray(points[0]))
                        isarray = true;

                    var ring = [];
                    for (i = 0; i < points.length; i++) {
                        var p = points[i];

                        if (isarray)
                            ring.push([p[0], p[1]]);
                        else
                            ring.push([p.x, p.y]);
                    }

                    var linewidth = 2;
                    var color = new Color([0, 0, 255, 0.75]);
                    var slineSymbol = new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, color, linewidth);
                    if (option && option.lineStyle) {
                        if (option.lineStyle.width)
                            linewidth = option.lineStyle.width;
                        color = new Color([option.lineStyle.r, option.lineStyle.g, option.lineStyle.b, option.lineStyle.a]);
                        slineSymbol = new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, color, linewidth);
                    }


                    //填充样式
                    //STYLE_BACKWARD_DIAGONAL	The fill is backward diagonal lines.
                    //STYLE_CROSS	The fill is a cross.
                    //STYLE_DIAGONAL_CROSS	The fill is a diagonal cross.
                    //STYLE_FORWARD_DIAGONAL	The fill is forward diagonal lines.
                    //STYLE_HORIZONTAL	The fill is horizontal lines.
                    //STYLE_NULL	The polygon has no fill.
                    //STYLE_SOLID	The fill is solid.
                    //STYLE_VERTICAL
                    var fillColor = new Color([255, 255, 0, 0.3]);
                    var fillSymbol;
                    if (option && option.fillPicUrl)
                        fillSymbol = new PictureFillSymbol(option.fillPicUrl, slineSymbol, 42, 42);
                    else {
                        fillSymbol = SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, slineSymbol, fillColor);
                        if (option && option.fillStyle) {
                            var fillStyle = option.fillStyle;
                            color = new Color([fillStyle.r, fillStyle.g, fillStyle.b, fillStyle.a]);
                            fillSymbol.setColor(color);

                            if (fillStyle.style)
                                fillSymbol.setStyle(fillStyle.style);
                        }
                    }

                    //var polygonJson = { "rings": ring, "spatialReference": spatialReference };
                    var polygon = new Polygon(ring);
                    polygon.setSpatialReference(this.spatialReference);

                    var graphic = {};
                    var infoTemplate = {};
                    if (option && option.template && option.template.attrs) {
                        graphic = new Graphic(polygon, fillSymbol, option.template.attrs);

                        infoTemplate = setinfoTemplate(option.template);
                        if (infoTemplate)
                            graphic.setInfoTemplate(infoTemplate);

                    } else {
                        graphic = new Graphic(polygon, fillSymbol);

                    }
                    //设置图标属性信息模板
                    if (option && option.attributes)
                        graphic.attributes = option.attributes;

                    myGraphicsLayer.add(graphic);

                    //缩放到面
                    if (option && option.isMoveTo)
                        this.appMap.setExtent(polygon.getExtent(), true);

                    return graphic;
                },
                //画文本信息 title :text, x:0,y:0, options={ layerid:layerid, style:{ size:14,r:255,g:0,b:0,xOffset:0,yOffset:0}  }
                drawText: function (text, x, y, options) {
                    if (!$.isNumeric(x) || !$.isNumeric(y)) {
                        console.log("坐标值未设置!");
                        return;
                    }

                    var size = 12;
                    var color = new Color([255, 0, 0]);

                    var txtGraphicsLayer = getGraphicsLayer(this.appMap, options && options.layerid);

                    if (options && options.style && options.style.size)
                        size = options.size;
                    if (options && options.style) {
                        if (options.style.r >= 0 && options.style.g >= 0 && options.style.b >= 0)
                            color = new Color([options.style.r, options.style.g, options.style.b]);
                    }


                    if (text) {
                        var point = new Point(x, y, this.spatialReference);

                        var textsyb = new TextSymbol(text, new Font(size), color);

                        if (options && $.isNumeric(options.xOffset) && $.isNumeric(options.yOffset))
                            textsyb.setOffset(options.xOffset, options.yOffset);

                        var txtgraphic = new Graphic(point, textsyb);

                        txtGraphicsLayer.add(txtgraphic);
                    }

                    return txtgraphic;
                },
                //清除图标 layerid :图层id
                clearGraphics: function (layerid) {
                    var myGraphicsLayer;
                    //设置图形图层
                    if (layerid) {
                        myGraphicsLayer = this.appMap.getLayer(layerid);
                    }
                    else
                        myGraphicsLayer = this.appMap.getLayer(drawLyrId);

                    if (myGraphicsLayer)
                        myGraphicsLayer.clear();

                    flashgraphics = [];
                },
                //激活画点，线，面工具 drawEndFunc 回调
                startDrawTool: function (drawEndFunc) {
                    this.drawTool = new Draw(this.appMap);
                    if (drawEndFunc)
                        this.drawTool.on("draw-end", drawEndFunc);
                    return this.drawTool;
                },
                //图形编辑
                activateGraphicEdit: function (graphic) {
                    if (graphic) {
                        var tool = 0;
                        tool = tool | Edit.MOVE;
                        tool = tool | Edit.EDIT_VERTICES;
                        tool = tool | Edit.SCALE;
                        tool = tool | Edit.ROTATE;
                        tool = tool | Edit.EDIT_TEXT;
                        var options = {
                            allowAddVertices: true,
                            allowDeleteVertices: true,
                            uniformScaling: true
                        };
                        this.editTool.activate(tool, graphic, options);
                    }
                }


            });


        return declare("application.Map", null,
            {
                appMap: null,
                layerInfo: null,
                drawApi: null,
                arcgisServer: null,
                basemapToggle: null,
                spatialReference: null,
                tooltipDialog: null,
                //op={
                //mapDivId :地图 div id
                //arcgisServer : 地图服务地址 例:http://116.7.249.34:6080/arcgis/rest/services/XhsApp/
                //layerInfo : 图层配置信息 [ {layerName:隐患点,serverId:1},{layerName:设施点,serverId:2}.....] }
                constructor: function (op) {

                    if (op.ArcgisToken)
                        agstoken = op.ArcgisToken;

                    if (!op.mapDivId || !op.arcgisServer) {
                        console.log("未设置地图Div或图层服务!");
                        return;
                    }
                    this.layerInfo = [];
                    m_serverName = op.arcgisServer;
                    this.arcgisServer = op.arcgisServer;
                    if ($.isArray(op.layerInfo)) {
                        this.layerInfo = op.layerInfo;
                        layerInfos = op.layerInfo;
                    }
                    else {
                        console.log("图层信息layerInfo未设置!");
                        return;
                    }


                    this.spatialReference = new SpatialReference({ wkid: 4326 }); // 经伟度
                    if (op.spatialReference == 0)
                        this.spatialReference = new SpatialReference({ wkid: 102113 }); // 莫卡托


                    //
                    var centerX = 113.99897;
                    var centerY = 22.560083;



                    var mapconfig = {
                        basemap: "",
                        //lods: lods
                        zoom: 11
                    };

                    if (op.lods && $.isArray(op.lods))
                        mapconfig.lods = op.lods;
                    this.appMap = new Map(op.mapDivId, mapconfig);


                    if ($.isArray(op.centerLngLat) && op.centerLngLat.length == 2) {
                        centerX = op.centerLngLat[0];
                        centerY = op.centerLngLat[1];
                    }

                    var p = new Point(centerX, centerY, this.spatialReference);
                    this.appMap.centerAt(p);

                    //m_map = this.appMap;
                    //m_map.addLayer(new GraphicsLayer({ id: drawLyrId }));
                    //画点，线，面接口
                    this.drawApi = new map.Draw(this.appMap, this.spatialReference);


                    //this.tooltipDialog = new TooltipDialog({
                    //    id: "tooltipDg" + op.mapDivId
                    //    //,style: "position: absolute; width: 250px; font: normal normal normal 10pt Helvetica;z-index:100"
                    //});
                    //this.tooltipDialog.startup();

                },
                //设置坐标系 isLngLat=1: 经伟度,isLngLat=0:莫卡托
                setSpatialReference: function (isLngLat) {
                    if (isLngLat)
                        this.spatialReference = new SpatialReference({ wkid: 4326 });
                    else
                        this.spatialReference = new SpatialReference({ wkid: 102113 });

                    this.drawApi.spatialReference = this.spatialReference;
                },
                getSpatialReference: function () {
                    return this.spatialReference;
                },
                //添加一个图形图层
                newGraphicLayer: function (layerid) {
                    if (layerid)
                        return getGraphicsLayer(this.appMap, layerid);
                },
                //baseMapType： streets 矢量图,satellite:影像图
                //basemapToggleDiv :图层切换div id
                addGoogleLayer: function (baseMapType, basemapToggleDiv) {


                    var glBaseName = "gl_base";
                    var glPoiName = "gl_poi";
                    //添加谷歌在线地图
                    var glBase = new GoogleLayer({ id: glBaseName, basemap: baseMapType == "streets" ? "vector" : "image" });
                    glBase.setVisibility(true);
                    this.appMap.addLayer(glBase);
                    var glPoi = new GoogleLayer({ id: glPoiName, basemap: "poi" });
                    glPoi.setVisibility(baseMapType == "streets" ? false : true);
                    this.appMap.addLayer(glPoi);

                    var stackedToggleDiv = dijit.byId(basemapToggleDiv);
                    if (stackedToggleDiv) {
                        stackedToggleDiv.destroyRecursive(true);
                    }
                    var toggle = new BasemapToggle2({
                        map: this.appMap,
                        basemap: baseMapType == "streets" ? "satellite" : "streets",
                        defaultBasemap: baseMapType
                    }, basemapToggleDiv);
                    var map = this.appMap;
                    toggle.setBasemap = function (basemap) {
                        setBaseMap(map, basemap);
                    };
                    toggle.startup();
                    this.basemapToggle = toggle;

                },
                //高德地图
                //baseMapType： streets 矢量图,satellite:影像图
                //basemapToggleDiv :图层切换div id
                addGaodeLayer: function (baseMapType, basemapToggleDiv) {
                    var glBaseName = "gd_road";
                    var glPoiName = "gd_st";
                    //添加谷歌在线地图
                    var glBase = new gaodeLayer({ id: glBaseName, layertype: "road" }); //GoogleLayer({ id: glBaseName, basemap: baseMapType == "streets" ? "vector" : "image" });
                    glBase.setVisibility(true);
                    this.appMap.addLayer(glBase);

                    var glPoi = new gaodeLayer({ id: glPoiName, layertype: "st" });  //GoogleLayer({ id: glPoiName, basemap: "poi" });
                    glPoi.setVisibility(baseMapType == "streets" ? false : true);
                    this.appMap.addLayer(glPoi);

                    var lable = new gaodeLayer({ id: "gd_label", layertype: "label" });
                    lable.setVisibility(baseMapType == "streets" ? false : true);
                    this.appMap.addLayer(lable);

                    var stackedToggleDiv = dijit.byId(basemapToggleDiv);
                    if (stackedToggleDiv) {
                        stackedToggleDiv.destroyRecursive(true);
                    }
                    var toggle = new BasemapToggle2({
                        map: this.appMap,
                        basemap: baseMapType == "streets" ? "satellite" : "streets",
                        defaultBasemap: baseMapType
                    }, basemapToggleDiv);
                    var map = this.appMap;
                    toggle.setBasemap = function (basemap) {
                        setGaodeBaseMap(map, basemap);
                    };
                    toggle.startup();
                    this.basemapToggle = toggle;
                },
                //百度地图
                //baseMapType： streets 矢量图,satellite:影像图
                //basemapToggleDiv :图层切换div id
                addBaiduLayer: function (baseMapType, basemapToggleDiv) {
                    var glBaseName = "gd_road";
                    var glPoiName = "gd_st";
                    //
                    var glBase = new BaiduLayer({ id: glBaseName, layertype: "road" });
                    glBase.setVisibility(true);
                    this.appMap.addLayer(glBase);

                    var glPoi = new BaiduLayer({ id: glPoiName, layertype: "st" });
                    glPoi.setVisibility(baseMapType == "streets" ? false : true);
                    this.appMap.addLayer(glPoi);

                    var lable = new BaiduLayer({ id: "gd_label", layertype: "label" });
                    lable.setVisibility(baseMapType == "streets" ? false : true);
                    this.appMap.addLayer(lable);

                    var stackedToggleDiv = dijit.byId(basemapToggleDiv);
                    if (stackedToggleDiv) {
                        stackedToggleDiv.destroyRecursive(true);
                    }
                    var toggle = new BasemapToggle2({
                        map: this.appMap,
                        basemap: baseMapType == "streets" ? "satellite" : "streets",
                        defaultBasemap: baseMapType
                    }, basemapToggleDiv);
                    var map = this.appMap;
                    toggle.setBasemap = function (basemap) {
                        setGaodeBaseMap(map, basemap);
                    };
                    toggle.startup();
                    this.basemapToggle = toggle;
                },
                //添加矢量地图 url:矢量图地址
                addDynamicMap: function (url) {
                    if (url) {
                        var baseLayer = new ArcGISDynamicMapServiceLayer(url, { id: "baseLayer" });
                        this.appMap.addLayer(baseLayer);
                        return baseLayer;
                    }
                },
                //创建要素层
                //layerName:"图层名", parm={ showMouseCursor:true , maxScale :0,minScale :0, showTooltip:false,  showInfoTemplate :false,definitionExpression: "unitid=1" }
                addFeatureLayer: function (layerName, parm) {
                    var lyrid = getLayerServeridByName(layerName);
                    if (!lyrid && lyrid != 0) {
                        console.log("未找到图层信息!");
                        return;
                    }

                    maxScale = 0;
                    minScale = 0;
                    if (parm && parm.maxScale)
                        maxScale = parm.maxScale;
                    if (parm && parm.minScale)
                        minScale = parm.minScale;

                    var url = m_serverName + "/FeatureServer/" + lyrid + agstoken;
                    var options = {
                        mode: esri.layers.FeatureLayer.MODE_ONDEMAND,
                        outFields: ["*"],
                        id: lyrid,
                        maxScale: maxScale,
                        minScale: minScale,
                    };
                    var layer = new FeatureLayer(url, options);
                    if (parm && parm.showInfoTemplate)
                        layer.infoTemplate = new esri.InfoTemplate();

                    if (parm && parm.definitionExpression)
                        layer.setDefinitionExpression(parm.definitionExpression);

                    if (parm && parm.showTooltip) {
                        this.appMap.graphics.enableMouseEvents();
                        this.appMap.graphics.on("mouse-out", function () {
                            this.appMap.graphics.clear();
                            dijitPopup.close(this.tooltipDialog);
                        });

                        var tooltip = this.tooltipDialog
                        layer.on("mouse-over", function (evt) {
                            //var content = esriLang.substitute(evt.graphic.attributes, t);
                            //this.tooltipDialog.setContent(content);
                            domStyle.set(tooltip.domNode, "opacity", 0.85);
                            dijitPopup.open({
                                popup: tooltip,
                                x: evt.pageX,
                                y: evt.pageY
                            });
                        });
                    }

                    if(parm && parm.showMouseCursor)
                    {
                        var m_map=this.appMap;
                        layer.on("mouse-over", function() {
                            m_map.setMapCursor("pointer");
                        });
                        layer.on("mouse-out", function() {
                            m_map.setMapCursor("default");
                        });
                    }

                    this.appMap.addLayer(layer);

                    return layer;
                },
                //添加聚合图层
                //聚合信息clusterInfo = { layername: "枪机,球机", inScaleLevel: 16, data: data.item } :获取图层所有数据data：返回json格式数据:{ lng:123,lat:12, }
                //distance:聚合距离 :默认100米
                //rendererimg 聚合图标 [{start:0,end:5,img:"images/BluePin1LargeB.png",size:32 },{start:5,end:200,img:"images/GreenPin1LargeB.png",size:64 },.....]
                //options其它可选属性{
                //labelyOffset:10, //聚合数字偏移量
                //labelxOffset:10,
                //singleColor:#888 //点击显示单个顔色
                //  }
                addClusterLayer: function (layerid, clusterInfo, distance, rendererimg, options) {

                    if (!clusterInfo || !clusterInfo.data) {
                        console.log("数据不能为空!");
                        return;
                    }
                    if (!rendererimg) {
                        console.log("聚合图标参数不能为空!");
                        return;
                    }
                    if (!distance)
                        distance = 100;

                    var resultInfo = {};
                    var wgs = new SpatialReference({
                        "wkid": 4326
                    });
                    resultInfo.data = arrayUtils.map(clusterInfo.data, function (p) {

                        var latlng;
                        if (p.x && p.y)
                            latlng = new Point(parseFloat(p.x), parseFloat(p.y), wgs);
                        else
                            latlng = new Point(parseFloat(p.lng), parseFloat(p.lat), wgs);

                        var webMercator = webMercatorUtils.geographicToWebMercator(latlng);
                        return {
                            "x": webMercator.x,
                            "y": webMercator.y,
                            "attributes": p
                        };
                    });

                    var labelyOffset = 10;
                    var labelxOffset = 0;
                    var singleColor = "#888";
                    if (options && options.labelyOffset)
                        labelyOffset = options.labelyOffset;
                    if (options && options.labelxOffset)
                        labelxOffset = options.labelxOffset;
                    if (options && options.singleColor)
                        singleColor = options.singleColor;

                    // cluster layer that uses OpenLayers style clustering
                    var clusterLayer = new ClusterLayer({
                        "data": resultInfo.data,
                        "distance": distance,
                        "id": layerid,
                        "labelColor": "#fff",
                        "labelyOffset": labelyOffset,
                        "labelxOffset": labelxOffset,
                        "resolution": this.appMap.extent.getWidth() / this.appMap.width,
                        "singleColor": singleColor,
                        "singleTemplate": ""//popupTemplate
                    });

                    var defaultSym = new SimpleMarkerSymbol().setSize(4);
                    var renderer = new ClassBreaksRenderer(defaultSym, "clusterCount");

                    for (var i = 0; i < rendererimg.length; i++) {
                        var img = new PictureMarkerSymbol(rendererimg[i].img, rendererimg[i].size, rendererimg[i].size).setOffset(0, 15);
                        renderer.addBreak(rendererimg[i].start, rendererimg[i].end, img);
                    }

                    clusterLayer.setRenderer(renderer);
                    this.appMap.addLayer(clusterLayer);

                    // close the info window when the map is clicked
                    this.appMap.on("click", function () { clusterLayer.clearSingles(); });
                    // close the info window when esc is pressed
                    this.appMap.on("key-down", function (e) {
                        if (e.keyCode === 27) {
                            clusterLayer.clearSingles();
                        }
                    });

                    if (clusterInfo.layername) {
                        var map = this.appMap;
                        this.appMap.on("zoom-end", function (e) {


                            var lrys = clusterInfo.layername.split(",");
                            if (e.level >= clusterInfo.inscalelevel) {
                                lrys.forEach(function (layerName) {
                                    var lyrid = getLayerServeridByName(layerName);
                                    var layer = map.getLayer(lyrid);
                                    if (layer)
                                        layer.setVisibility(true);
                                });
                                clusterLayer.setVisibility(false);
                            }
                            else {
                                lrys.forEach(function (layerName) {
                                    var lyrid = getLayerServeridByName(layerName);
                                    var layer = map.getLayer(lyrid);
                                    if (layer)
                                        layer.setVisibility(false);
                                });
                                clusterLayer.setVisibility(true);
                            }

                        });

                    }

                    return clusterLayer;

                },
                //通过图形查询图层数据
                queryByGeometry: function (layerName, geometry, callback, options) {
                    var lyrid = getLayerServeridByName(layerName);
                    var url = m_serverName + "/FeatureServer/" + lyrid;
                    var queryTask = new esri.tasks.QueryTask(url);

                    var query = new esri.tasks.Query();
                    query.outSpatialReference = this.spatialReference;
                    query.returnGeometry = true;
                    query.outFields = ["*"];
                    if (options && options.outFields)
                    { query.outFields = options.outFields; }
                    if (options && options.where)
                    { query.where = options.where; }

                    query.geometry = geometry;
                    queryTask.execute(query, callback);

                },
                //通过图形查询所有图层数据 url为mapServer geometry:点，线
                IdentifyByGeometry: function (url, geometry, tolerance, callback) {

                    var map = this.appMap;
                    require(["esri/tasks/IdentifyTask", "esri/tasks/IdentifyParameters"], function (IdentifyTask, IdentifyParameters) {
                        var identify = new IdentifyTask(url);
                        var identifyParams = new IdentifyParameters();

                        identifyParams.returnGeometry = true;
                        identifyParams.spatialReference = this.spatialReference;
                        identifyParams.geometry = geometry;
                        identifyParams.tolerance = tolerance;
                        identifyParams.mapExtent = map.extent;
                        //identifyParams.mapExtent = map.extent;
                        identify.execute(identifyParams, callback, function (evt) {

                            var kk = evt;
                        });

                    });

                },
                ///获取图层
                getFeatureLayerByName: function (name) {
                    if (!name) return null;
                    var lyrid = getLayerServeridByName(name);
                    if (!lyrid && lyrid != 0) {
                        console.log("未找到图层信息!");
                        return null;
                    }

                    return this.appMap.getLayer(lyrid);

                },
                //刷新图层
                refreshLayer: function (layerid) {
                    if (layerid != null) {
                        var layer = this.appMap.getLayer(layerid);
                        if (layer != null) {
                            layer.refresh();
                        } else {
                            console.log("找不到ID为{ " + layerid + " }图层");
                        }
                    }
                },
                //获取图层要素  layerName : 隐患点, oid: 10 callback:回调 function(data){  }
                getFeatureByOid: function (layerName, oid, callback) {
                    this.getFeatureByWhere(layerName, "objectid =" + oid, callback);
                },
                getFeatureByWhere: function (layerName, where, callback) {

                    if (this.appMap == null) {
                        console.log("找不到地图对象!appMap");
                        return;
                    }
                    var layerid = getLayerServeridByName(layerName);
                    if (!layerid) {
                        console.log("找不到{ " + layerName + " }图层");
                        return;
                    }
                    var layer = this.appMap.getLayer(layerid);
                    if (layer == null) {
                        console.log("找不到{ " + layerName + " }图层");
                        return;
                    }

                    var queryTask = new esri.tasks.QueryTask(layer.url);
                    query = new esri.tasks.Query();
                    query.outSpatialReference = this.spatialReference;
                    query.returnGeometry = true;
                    query.outFields = ["*"];
                    query.where = where;
                    queryTask.execute(query, callback);
                },
                //能过坐标定位
                zoomTobyXY: function (x, y, minZoom) {
                    var point = new Point(x, y, this.spatialReference);
                    //var zoom = this.appMap.getZoom();
                    //if (minZoom  && zoom < minZoom) {
                    //    this.appMap.centerAndZoom(point, minZoom);
                    //}
                    //else {
                    //    this.appMap.centerAt(point);
                    //}
                    this.appMap.centerAndZoom(point, minZoom);
                },
                //通过 objectid 定位 parm ={ layerName : 隐患点, oid: 10  }
                zoomToByOid: function (layerName, oid) {

                    var appMapObj = this;
                    this.getFeatureByOid(layerName, oid, function (fset) {

                        if (fset.features.length === 1) {

                            var x = fset.features[0].geometry.x;
                            var y = fset.features[0].geometry.y;
                            appMapObj.zoomTobyXY(x, y, 13);

                            appMapObj.drawApi.clearGraphics();
                            appMapObj.drawApi.drawPoint(x, y);

                        } else {
                            console.log("找不到ID为：" + oid + "的要素!");
                        }

                    });

                },
                //多点定位 points:[{x:114.2,y:25}], minZoom：定位比例尽,  showPointOptions 显示点/不显示
                setMapExtendByPoints: function (points, minZoom, showPointOptions) {
console.log(showPointOptions);
                    var isShowPoint = false;
                    var layerid = "multilyerid";

                    if (showPointOptions && showPointOptions.isShowPoint){

                        isShowPoint = true;

                        showPointOptions.layerid=layerid;
                    }

                    if (!points || points.length == 0) {
                        console.log("没有坐标值!");
                        this.drawApi.clearGraphics(layerid);
                        return;
                    }

                    if (isShowPoint)
                        this.drawApi.clearGraphics(layerid);

                    if (points.length == 1) {

                        if (isShowPoint) {
                            // this.drawApi.drawPoint(points[i].x, points[i].y);
                            // updated by pello 2016 11 28
                            this.drawApi.drawPoint(points[0].x, points[0].y, showPointOptions);
                        }

                        this.zoomTobyXY(points[0].x, points[0].y, minZoom)
                    }
                    else if (points.length > 1) {
                        var multiPoint = new Multipoint(this.spatialReference);
                        for (i = 0; i < points.length; i++) {
                            var point = new Point(points[i].x, points[i].y, this.spatialReference);
                            multiPoint.addPoint(point);

                            if (isShowPoint)
                                this.drawApi.drawPoint(points[i].x, points[i].y, showPointOptions);


                        }
                        this.appMap.setExtent(multiPoint.getExtent(), true);

                    }

                },
                //莫卡托转经伟度
                xyToLngLat: function (x, y) {
                    var _pLngLat = webMercatorUtils.xyToLngLat(x, y);
                    return _pLngLat;
                },
                //莫卡托转经伟度
                lngLatToXY: function (lng, lat) {
                    var _pLngLat = webMercatorUtils.lngLatToXY(lng, lat);
                    return _pLngLat;
                },
                //火星==>百度
                mars2Badiu: function (ggLngLat) {
                    var x = ggLngLat.lng, y = ggLngLat.lat;
                    var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
                    var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
                    var bd_lng = z * Math.cos(theta) + 0.0065;
                    var bd_lat = z * Math.sin(theta) + 0.006;

                    return { lng: bd_lng, lat: bd_lat }
                },
                //百度==>火星
                baidu2Mars: function (bdLngLat) {
                    var x = bdLngLat.lng - 0.0065, y = bdLngLat.lat - 0.006;
                    var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
                    var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
                    gg_lng = z * Math.cos(theta);
                    gg_lat = z * Math.sin(theta);

                    return { lng: gg_lng, lat: gg_lat }
                },
                //通过经纬度查询两点间距离
                getDistance: function (lat1, lng1, lat2, lng2) {
                    var radLat1 = this.rad(lat1);
                    var radLat2 = this.rad(lat2);
                    var a = radLat1 - radLat2;
                    var b = this.rad(lng1) - this.rad(lng2);
                    var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                            Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
                    s = s * this.EARTH_RADIUS;
                    s = Math.round(s * 10000) / 10000;
                    return s;
                },
                //获取中心点points:[[114, 24],[114,23].....]
                getCenterPoint: function (points) {

                    var centerPoint = { x: 0, y: 0 };

                    if (points.length == 1) {
                        centerPoint = { x: points[0][0], y: points[0][1] }
                    }
                    else if (points.length === 2) {

                        var x = ((points[0][0] + points[0][1]) / 2).toFixed(6);
                        var y = ((points[1][0] + points[1][1]) / 2).toFixed(6);

                        centerPoint = { x: x, y: y };
                    }
                    else if (points.length > 2) {
                        var polygon = new Polygon(points);
                        polygon.setSpatialReference(this.spatialReference);

                        centerPoint = polygon.getExtent().getCenter();
                    }
                    else {

                        console.log("error:" + points);
                    }
                    return centerPoint;



                }

            });


        function setBaseMap(m_map, type) {
            var glbase = m_map.getLayer("gl_base");
            var glpoi = m_map.getLayer("gl_poi");
            if (glbase == null || glpoi == null) {
                return;
            }
            if (type === "streets") {
                //glbase.basemap = "vector";
                glbase.setBasemap("vector");
                glpoi.setVisibility(false);
            }
            else if (type === "satellite") {
                //glbase.basemap = "image";
                glbase.setBasemap("image");
                glpoi.setVisibility(true);
            }
            glpoi.refresh();
            glbase.refresh();
        }
        //高德底图切换
        function setGaodeBaseMap(m_map, type) {
            var gd_road = m_map.getLayer("gd_road");
            var gd_st = m_map.getLayer("gd_st");
            var gd_label = m_map.getLayer("gd_label");
            if (gd_road == null || gd_st == null) {
                return;
            }
            if (type === "streets") {
                gd_road.setVisibility(true);
                gd_st.setVisibility(false);
                gd_label.setVisibility(false);
            }
            else if (type === "satellite") {
                gd_road.setVisibility(false);
                gd_st.setVisibility(true);
                gd_label.setVisibility(true);
            }
            gd_road.refresh();
            gd_st.refresh();
            gd_label.refresh();
        }

        function setinfoTemplate(template) {


            var infoTemplate;
            var attrs = "";

            if (!template) return infoTemplate;

            if (template.displayattributes) {
                $.each(template.displayattributes, function (key, value) {
                    attrs += key + ": " + value + " <br/>";
                });
                infoTemplate = new InfoTemplate("信息", attrs);
            }
            else {
                if (template.content)
                    infoTemplate = new InfoTemplate("信息", template.content);
            }

            return infoTemplate;
        }

        //根据图层名字获取serverid
        function getLayerServeridByName(lyrName) {
            var serverid;
            $.each(layerInfos, function (index, d) {
                if (d.layerName == lyrName) {
                    serverid = d.serverId;
                    return serverid;
                }
            });

            return serverid;
        }
        //设置画点线面的图层
        function getGraphicsLayer(m_map, id) {
            var myGraphicsLayer;
            //设置图形图层
            var layerid = drawLyrId;
            if (id)
                layerid = id

            var myGraphicsLayer = m_map.getLayer(layerid);
            if (!myGraphicsLayer) {
                myGraphicsLayer = new GraphicsLayer({ id: layerid });
                graphicsLayers.push(myGraphicsLayer);
                m_map.addLayer(myGraphicsLayer);
                myGraphicsLayer.on("mouse-over", function() {
                    m_map.setMapCursor("pointer");
                });
                myGraphicsLayer.on("mouse-out", function() {
                    m_map.setMapCursor("default");
                });
            }

            return myGraphicsLayer;
        }

        function newGuid() {

            var s4 = (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
            return (s4 + s4 + "-" + s4 + "-" + s4 + "-" + s4 + "-" + s4 + s4 + s4);
        }
    }
);